package cn.lanqiao.springbootproject.filter;

import cn.lanqiao.springbootproject.util.CurrentUserUtil;
import cn.lanqiao.springbootproject.util.Result;
import cn.lanqiao.springbootproject.vo.UserRoleVO;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * 刷新redis中的token有效期
 */
@Slf4j
@Component
public class LoginRedisFilter implements Filter {

    @Autowired
    RedisTemplate redisTemplate;


    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //准备对象
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        HttpServletRequest request = (HttpServletRequest) servletRequest;

        log.info(request.getMethod());

        try {
            String token = request.getHeader("Authorization");
            if (token != null) {
                //获得用户数据
                token = token.substring(7);
                UserRoleVO userRoleVO = (UserRoleVO) redisTemplate.opsForValue().get("userToken:" + token);
                if (userRoleVO != null) {
                    //刷新时间
                    redisTemplate.expire("userToken:" + token, 30, TimeUnit.MINUTES);
                    //用户数据存入ThreadLocal, 为后续鉴权提供数据
                    CurrentUserUtil.set(userRoleVO);
                } else {
                    failResult(604, "token无效！", response);
                }
            }
        } catch (Exception e) {
            failResult(610, "未知错误！", response);
            return;
        }
        //调用下一个 filter 或者 servlet
        filterChain.doFilter(servletRequest, servletResponse);

    }

    /**
     * 验证失败统一向前端返回错误结果
     *
     * @param code     错误码
     * @param message  错误信息
     * @param response 响应对象
     */
    public boolean failResult(int code, String message, HttpServletResponse response) {
        try {
            ObjectMapper objectMapper = new ObjectMapper();//使用jackson，也可以使用fastjson
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter().print(objectMapper.writeValueAsString(Result.error(code, message)));
            response.flushBuffer();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }
}
